package cn.yitun.chat.yitunserverimapicore.business.group.service.impl;

import cn.yitun.chat.yituncommonmessage.ExceptionEnum;
import cn.yitun.chat.yituncommonmessage.Info;
import cn.yitun.chat.yituncommonutil.YitunCollectionUtil;
import cn.yitun.chat.yituncommonutil.YitunStringUtil;
import cn.yitun.chat.yitunservercommonlib.converter.dto2vo.group.GroupJoinApplyDto2VoConverter;
import cn.yitun.chat.yitunservercommonlib.crud.yitun.CrudServiceImpl;
import cn.yitun.chat.yitunservercommonlib.dataentity.data.base.group.GroupJoinResult;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.group.GroupJoinApplyDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.group.GroupJoinVerifyAnswerDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.po.group.GroupJoinApplyInfo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.group.GroupJoinApplyVo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.group.GroupJoinVerifyQuestionVo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.group.GroupMemberVo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.group.GroupSettingVo;
import cn.yitun.chat.yitunservercommonlib.enums.groupChat.GroupJoinVerifySettingTypeEnums;
import cn.yitun.chat.yitunservercommonlib.enums.userChat.UserRequestTypeEnums;
import cn.yitun.chat.yitunservercommonlib.util.NumUtil;
import cn.yitun.chat.yitunservercommonlib.util.R;
import cn.yitun.chat.yitunservercommonlib.util.codec.IdGen;
import cn.yitun.chat.yitunserverimapicore.business.group.service.GroupJoinService;
import cn.yitun.chat.yitunserverimbase.dao.group.GroupJoinApplyDao;
import cn.yitun.chat.yitunserverimbase.dao.group.GroupJoinVerifyAnswerDao;
import cn.yitun.chat.yitunserverimbase.dao.group.GroupJoinVerifyQuestionDao;
import cn.yitun.chat.yitunserverimbase.dao.group.GroupMemberDao;
import cn.yitun.chat.yitunserverimcore.general.main.biz.group.manager.GroupCategoryManager;
import cn.yitun.chat.yitunserverimcore.general.main.biz.group.manager.GroupJoinSettingManager;
import cn.yitun.chat.yitunserverimcore.general.main.biz.group.manager.GroupMemberManager;
import cn.yitun.chat.yitunserverimcore.general.main.biz.group.manager.GroupRelationManager;
import cn.yitun.chat.yitunserverimcore.general.main.push.group.GroupJoinPush;
import cn.yitun.chat.yitunserverimcore.general.main.push.group.GroupMemberPush;
import cn.yitun.chat.yitunserverimcore.general.main.push.group.GroupRelationPush;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Date 2019-01-23 22:01:34<br>
 * Description
 * @author yitun
 * @since 1.0.0
 */
@Service
@Transactional
public class GroupJoinServiceImpl
		extends CrudServiceImpl<GroupJoinApplyDao, GroupJoinApplyDto, GroupJoinApplyInfo, GroupJoinApplyVo>
		implements GroupJoinService {

	@Resource
	private GroupMemberDao groupMemberDAO;
	@Resource
	private GroupJoinVerifyAnswerDao groupJoinVerifyAnswerDAO;
	@Resource
	private GroupJoinVerifyQuestionDao groupJoinVerifyQuestionDAO;

	@Resource
	private GroupJoinSettingManager groupJoinSettingManager;
	@Resource
	private GroupCategoryManager groupCategoryManager;
	@Resource
	private GroupMemberManager groupMemberManager;
	@Resource
	private GroupRelationManager groupRelationManager;

	@Resource
	private GroupMemberPush groupMemberPush;
	@Resource
	private GroupRelationPush groupRelationPush;
	@Resource
	private GroupJoinPush groupJoinPush;

	/**
	 * Date 2019-01-24 22:24:41<br>
	 * Description 用户申请加入群
	 * @author yitun
	 * @param request
	 * @param answerList
	 * @return
	 * @since 1.0.0
	 */
	public Info joinApply(GroupJoinApplyDto request, List<GroupJoinVerifyAnswerDto> answerList) {
		Info info = new Info();
		Long applyUserId = request.getApplyUserId();
		Long requestCategoryId = request.getCategoryId();
		// 备注名
		String requestRemark = request.getRemark();

		Long groupId = request.getGroupId();

		String requestAnswer = request.getAnswer();
		// 附加消息
		// String requestMessage = request.getMessage();

		GroupMemberVo m = groupMemberDAO.getVOByGroupIdUserId(groupId, applyUserId);

		if (null != m) {
			info.addWarning(ExceptionEnum.SOCK_GROUP_JOIN_EXISTS);
			return info;
		}
		List<Long> userList = new ArrayList<>(1);
		userList.add(applyUserId);
		List<GroupJoinApplyVo> list = dao.listVO(R.param("groupId", groupId).put("userIds", userList));
		if (YitunCollectionUtil.isNotEmpty(list)) {
			info.addWarning(ExceptionEnum.SOCK_GROUP_JOIN_EXISTS);
			return info;
		}
		// 先获取安全设置
		GroupSettingVo setting = groupJoinSettingManager.getByGroupId(groupId);

		String verifyType = setting.getJoinType();
		String settingAnswer = setting.getAnswer();

		String handleType = UserRequestTypeEnums.HANDLE_TYPE_UNTREATED.getType();
		if (GroupJoinVerifySettingTypeEnums.VERIFY_TYPE_NEVER.getType().equals(verifyType) || GroupJoinVerifySettingTypeEnums.VERIFY_TYPE_INVITE.getType().equals(verifyType)) {
			info.addWarning(ExceptionEnum.SOCK_GROUP_JOIN_NOT_ALLOW);
			return info;
		} else if (GroupJoinVerifySettingTypeEnums.VERIFY_TYPE_ANY.getType().equals(verifyType)) {
			// 如果允许任何人加入，那么直接添加
			Long categoryId = NumUtil.isValid(requestCategoryId) ? requestCategoryId : groupCategoryManager.getOrCreateDefaultCategoryId(applyUserId);

			handleType = UserRequestTypeEnums.HANDLE_TYPE_ACCEPT.getType();

			GroupJoinApplyDto join = addGroupJoinRequest(handleType, request, answerList, setting);

			if (!groupRelationManager.has(applyUserId, groupId)) {
				groupRelationManager.add(groupId, applyUserId, categoryId, requestRemark);
			}

			if (!groupMemberManager.inGroup(groupId, applyUserId)) {
				groupMemberManager.add(groupId, applyUserId);
			}
			groupRelationPush.pushAdd(IdGen.getNumber(), groupId, applyUserId);
			handleJoinResponse(GroupJoinApplyDto2VoConverter.INSTANCE.dto2vo(join), "");
		} else if (GroupJoinVerifySettingTypeEnums.VERIFY_TYPE_ANSWER.getType().equals(verifyType)) {
			// 如果是回答问题，那么回答正确后直接添加
			if (YitunStringUtil.isEmpty(requestAnswer)) {
				info.addWarning(ExceptionEnum.SOCK_CONTACT_CATEGORY_NEED_ANSWER);
				return info;
			}

			String ra = requestAnswer.toLowerCase().trim();
			String sa = settingAnswer.toLowerCase().trim();

			if (!ra.equals(sa)) {
				info.addWarning(ExceptionEnum.SOCK_CONTACT_CATEGORY_WRONG_ANSWER);
				return info;
			}

			handleType = UserRequestTypeEnums.HANDLE_TYPE_ACCEPT.getType();
			Long categoryId = NumUtil.isValid(requestCategoryId) ? requestCategoryId : groupCategoryManager.getOrCreateDefaultCategoryId(applyUserId);

			GroupJoinApplyDto join = addGroupJoinRequest(handleType, request, answerList, setting);

			if (!groupRelationManager.has(applyUserId, groupId)) {
				groupRelationManager.add(groupId, applyUserId, categoryId, requestRemark);
			}

			if (!groupMemberManager.inGroup(groupId, applyUserId)) {
				groupMemberManager.add(groupId, applyUserId);
			}
			groupRelationPush.pushAdd(IdGen.getNumber(), groupId, applyUserId);
			handleJoinResponse(GroupJoinApplyDto2VoConverter.INSTANCE.dto2vo(join), "");
		} else if (GroupJoinVerifySettingTypeEnums.VERIFY_TYPE_AUTH.getType().equals(verifyType)) {
			// 如果需要验证，那么将请求信息保存，待管理员验证
			GroupJoinApplyDto join = addGroupJoinRequest(handleType, request, answerList, setting);
			Long applyId = join.getId();// 请求记录id
			// 推送添加请信息
			List<Long> userIds = groupMemberManager.getGroupAdminAndOwnerUserIdList(groupId);
			pushJoinApply(groupId, applyId, userIds);
		} else if (GroupJoinVerifySettingTypeEnums.VERIFY_TYPE_CONFIRM.getType().equals(verifyType)) {
			GroupJoinApplyDto joinRequest = addGroupJoinRequest(handleType, request, answerList, setting);
			Long applyId = joinRequest.getId();// 请求记录id
			// 推送添加请信息
			List<Long> userIds = groupMemberManager.getGroupAdminAndOwnerUserIdList(groupId);
			pushJoinApply(groupId, applyId, userIds);
		}
		return info;
	}

	/**
	 * 添加入群请求
	 */
	private GroupJoinApplyDto addGroupJoinRequest(String handleType, GroupJoinApplyDto request, List<GroupJoinVerifyAnswerDto> answerList, GroupSettingVo setting) {

		Long applyUserId = request.getApplyUserId();
		Long requestCategoryId = request.getCategoryId();
		// 备注名
		String requestRemark = request.getRemark();

		Long groupId = request.getGroupId();

		String requestAnswer = request.getAnswer();
		// 附加消息
		String requestMessage = request.getMessage();

		// 先获取安全设置

		String verifyType = setting.getJoinType();
		// String settingAnswer = setting.getAnswer();

		GroupJoinApplyDto joinRequest = new GroupJoinApplyDto();
		joinRequest.setApplyUserId(applyUserId);
		joinRequest.setGroupId(groupId);
		joinRequest.setCategoryId(requestCategoryId);
		joinRequest.setRemark(requestRemark);
		joinRequest.setVerifyType(verifyType);
		joinRequest.setQuestion(setting.getQuestion());
		joinRequest.setAnswer(requestAnswer);
		joinRequest.setHandleType(handleType);
		joinRequest.setMessage(requestMessage);
		joinRequest.setCreateBy(request.getCurrentUserId());
		joinRequest.setUpdateBy(request.getCurrentUserId());
//		joinRequest.setHandleUserId(request.getCurrentUserId());
//		joinRequest.setHandleUserPosition(groupMemberDAO.getVOByGroupIdUserId(groupId, applyUserId).getPosition());

		dao.save(joinRequest);

		if (GroupJoinVerifySettingTypeEnums.VERIFY_TYPE_CONFIRM.getType().equals(verifyType) && null != answerList && !answerList.isEmpty()) {
			Map<Long, GroupJoinVerifyQuestionVo> questionMap = new HashMap<>();
			List<GroupJoinVerifyQuestionVo> questionList = groupJoinVerifyQuestionDAO.listVO(
					R.param("groupId", groupId));
			if (YitunCollectionUtil.isNotEmpty(questionList)) {
				for (GroupJoinVerifyQuestionVo q : questionList) {
					questionMap.put(q.getId(), q);
				}
			}
			Long applyId = joinRequest.getId();// 请求消息的id(对应UserAddRequest中的id)

			List<GroupJoinVerifyAnswerDto> list = new ArrayList<>();
			for (GroupJoinVerifyAnswerDto a : answerList) {

				Long questionId = a.getQuestionId();// 问题id(对应GroupJoinVerifyQuestion中的id)
				String question = "";// 问题
				String answer = a.getAnswer();// 答案
				GroupJoinVerifyQuestionVo q = questionMap.get(questionId);
				if (null != q) {
					question = q.getQuestion();
				}
				GroupJoinVerifyAnswerDto bean = new GroupJoinVerifyAnswerDto();
				bean.setApplyId(applyId);
				bean.setApplyUserId(applyUserId);
				bean.setGroupId(groupId);
				bean.setQuestionId(questionId);
				bean.setQuestion(question);
				bean.setAnswer(answer);
				list.add(bean);
			}

			if (YitunCollectionUtil.isNotEmpty(list)) {
				groupJoinVerifyAnswerDAO.saveList(list);
			}
		}
		return joinRequest;
	}

	/**
	 * 处理入群请求
	 * @param handle
	 * @return
	 */
	public Info joinHandle(GroupJoinApplyDto handle) {
		// String handleUserId, String applyId,String handleType, String message

		List<Long> applyIds = handle.getApplyIds();// 请求记录id
		Long handleUserId = handle.getHandleUserId();
		String handleType = handle.getHandleType();// 处理结果：0:未处理 1:同意 2:拒绝 3:忽略
		String message = handle.getMessage();// 附加消息

		Info info = new Info();
		if (null != applyIds) {
			for (Long applyId : applyIds) {
				GroupJoinApplyVo joinApply = dao.getVO(applyId);

				if (null != joinApply) {

					Long categoryId = joinApply.getCategoryId();
					Long groupId = joinApply.getGroupId();
					Long applyUserId = joinApply.getApplyUserId();
					String remark = joinApply.getRemark();

					GroupMemberVo m = groupMemberDAO.getVOByGroupIdUserId(groupId, applyUserId);

					if (null != m) {
						return info;
					}

					String handleUserPosition = groupMemberManager.getPosition(groupId, handleUserId);

					boolean isAdmin = groupMemberManager.isAdmin(handleUserPosition);
					boolean isOwner = groupMemberManager.isOwner(handleUserPosition);
					if (isAdmin || isOwner) {
						joinApply.setHandleType(handleType);
						joinApply.setHandleUserId(handleUserId);
						joinApply.setHandleUserPosition(handleUserPosition);
						joinApply.setUpdateBy(handleUserId);

						dao.update(GroupJoinApplyDto2VoConverter.INSTANCE.vo2dto(joinApply));

						if (UserRequestTypeEnums.HANDLE_TYPE_ACCEPT.getType().equals(handleType)) {

							if (!groupRelationManager.has(applyUserId, groupId)) {
								groupRelationManager.add(groupId, applyUserId, categoryId, remark);
							}

							if (!groupMemberManager.inGroup(groupId, applyUserId)) {
								groupMemberManager.add(groupId, applyUserId);
							}

							List<Long> userIds = groupMemberManager.getGroupMemberUserIdList(groupId);
							groupRelationPush.pushAdd(IdGen.getNumber(),groupId, applyUserId);
							groupMemberPush.pushAdd(groupId, applyUserId, userIds);
						}
					}
					handleJoinResponse(joinApply, message);
				}
			}
		}
		return info;
	}

	private void pushJoinApply(Long groupId, Long applyId, List<Long> userIds) {
		groupJoinPush.pushJoinApply(IdGen.getNumber(), groupId, applyId, userIds);
	}

	private void handleJoinResponse(GroupJoinApplyVo joinApply, String message) {

		Long applyId = joinApply.getId();
		Long groupId = joinApply.getGroupId();
		Long applyUserId = joinApply.getApplyUserId();

		Long handleUserId = joinApply.getHandleUserId();
		String handleType = joinApply.getHandleType();// 处理结果：0:未处理 1:同意 2:拒绝 3:忽略
		// String message = joinApply.getMessage();

		GroupJoinResult result = new GroupJoinResult();
		result.setApplyId(applyId);
		result.setGroupId(groupId);
		result.setHandleType(handleType);
		result.setHandleUserId(handleUserId);
		// result.setMessage(message);
		groupJoinPush.pushJoinHandle(IdGen.getNumber(), result, applyUserId);
	}
}
